package com.example.huadu_server.house.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.huadu_server.appointment.mapper.AppointmentMapper;
import com.example.huadu_server.config.Response;
import com.example.huadu_server.house.dto.HouseUploadDTO;
import com.example.huadu_server.house.entity.BrowsingHistory;
import com.example.huadu_server.house.entity.Favorite;
import com.example.huadu_server.house.entity.House;
import com.example.huadu_server.house.entity.HouseImage;
import com.example.huadu_server.house.mapper.BrowsingHistoryMapper;
import com.example.huadu_server.house.mapper.FavoriteMapper;
import com.example.huadu_server.house.mapper.HouseMapper;
import com.example.huadu_server.house.mapper.HouseImageMapper;
import com.example.huadu_server.house.service.HouseService;
import com.example.huadu_server.landlord.entity.Landlord;
import com.example.huadu_server.landlord.mapper.LandlordMapper;
import com.example.huadu_server.oss.service.OssService;
import com.example.huadu_server.websocket.mapper.MessageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class HouseServiceImpl implements HouseService {

    @Autowired
    private HouseMapper houseMapper;

    @Autowired
    private HouseImageMapper houseImageMapper;

    @Autowired
    private LandlordMapper landlordMapper;

    @Autowired
    private BrowsingHistoryMapper browsingHistoryMapper;

    // 用于统计预约行为数据
    @Autowired
    private AppointmentMapper appointmentMapper;

    // 用于统计消息交互数据
    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")  // 从配置文件中注入发件人邮箱
    private String senderEmail;

    /**
     * 房东上传房源信息
     *
     * @param houseUploadDTO 房源上传的数据
     * @param landlordId     房东ID
     * @return
     */
    @Override
    @Transactional
    public Response<String> uploadHouse(HouseUploadDTO houseUploadDTO, int landlordId) {
        try {
            //保存房源信息
            House house = new House();
            house.setLandlordId(landlordId);
            house.setTitle(houseUploadDTO.getTitle());
            house.setDescription(houseUploadDTO.getDescription());
            house.setAddress(houseUploadDTO.getAddress());
            house.setHouseType(houseUploadDTO.getHouseType());
            house.setFacilities(houseUploadDTO.getFacilities());
            house.setCommunity(houseUploadDTO.getCommunity());
            house.setPrice(houseUploadDTO.getPrice());
            house.setArea(houseUploadDTO.getArea());
            house.setFloor(houseUploadDTO.getFloor());
            house.setBusinessArea(houseUploadDTO.getBusinessArea());
            house.setSubwayStation(houseUploadDTO.getSubwayStation());
            house.setLongitude(houseUploadDTO.getLongitude());
            house.setLatitude(houseUploadDTO.getLatitude());
            house.setLease(houseUploadDTO.getLease());
            house.setPayType(houseUploadDTO.getPayType());
            house.setTraffic(houseUploadDTO.getTraffic());
            house.setHouseStatus("pending"); // 默认状态为 pending
            house.setRemarks("待审核"); // 默认为空
            house.setTitleDeed(houseUploadDTO.getTitleDeed());//产权证明
            houseMapper.insert(house);

            // 保存房源图片
            int houseId = house.getId();
            for (String imageUrl : houseUploadDTO.getImageUrls()) {
                HouseImage houseImage = new HouseImage();
                houseImage.setHouseId(houseId);
                houseImage.setImageUrl(imageUrl);
                houseImageMapper.insert(houseImage);
            }

            return new Response<>(200, "房源上传成功", null);
        } catch (Exception e) {
            return new Response<>(500, "房源上传失败：" + e.getMessage(), null);
        }
    }

    /**
     * 搜索房源---采用双重搜索并将结果存到redis
     *
     * @param keyword 用户输入的搜索关键词
     * @return
     */
    @Override
    public Response<Map<String, Object>> searchHouses(String keyword, int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;

        // 如果关键字为空，调用 getHousesByPage 方法
        if (keyword == null || keyword.trim().isEmpty()) {
            return getHousesByPage(pageNo, pageSize);
        }

        // Redis 缓存键，处理空关键字
        String redisKey = "searchResults:" + (keyword.trim().isEmpty() ? "all" : keyword) + ":page:" + pageNo + ":size:" + pageSize;

        // 尝试从 Redis 获取缓存数据
        String cachedData = redisTemplate.opsForValue().get(redisKey);
        if (cachedData != null) {
            Map<String, Object> cachedResponse = JSON.parseObject(cachedData, Map.class);
            return new Response<>(200, "查询成功", cachedResponse);
        }

        // 调用全文搜索和模糊搜索，增加状态为 "available" 的条件
        List<House> fullTextResults = houseMapper.searchHousesByKeyword(keyword, offset, pageSize);
        int fullTextCount = houseMapper.getSearchCount(keyword);

        List<House> fallbackResults = houseMapper.searchHousesFallback(keyword, offset, pageSize);
        int fallbackCount = fallbackResults.size();

        // 合并结果
        Set<Long> seenIds = new HashSet<>();
        List<House> combinedResults = new ArrayList<>();

        // 合并全文搜索结果
        for (House house : fullTextResults) {
            if (seenIds.add(Long.valueOf(house.getId()))) {
                combinedResults.add(house);
            }
        }

        // 合并模糊搜索结果
        for (House house : fallbackResults) {
            if (seenIds.add(Long.valueOf(house.getId()))) {
                combinedResults.add(house);
            }
        }

        // 总数取最大值
        int totalCount = Math.max(fullTextCount, fallbackCount);

        // 为每个房源动态加载图片信息
        for (House house : combinedResults) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        // 对结果进行分页
        List<House> paginatedResults = combinedResults.stream()
                .skip(offset)
                .limit(pageSize)
                .collect(Collectors.toList());

        // 构造返回结果
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("total", totalCount);
        responseData.put("houses", paginatedResults);
        responseData.put("pageNo", pageNo);
        responseData.put("pageSize", pageSize);

        // 将结果存储到 Redis，设置过期时间为 10 分钟
        redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(responseData), 10, TimeUnit.MINUTES);

        return new Response<>(200, "查询成功", responseData);
    }

    /**
     * 筛选房源
     *
     * @param filters  筛选条件
     * @param pageNo   当前页码
     * @param pageSize 每页记录数
     * @return
     */
    @Override
    public Response<Map<String, Object>> filterHouses(Map<String, Object> filters, int pageNo, int pageSize) {
        // 过滤掉 filters 中值为 null 的键值对
        filters.entrySet().removeIf(entry -> entry.getValue() == null);

        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;
        List<House> filteredHouses;
        int total;
        // 调试日志，确认解析结果

        // 特殊筛选条件处理
        if (filters.containsKey("areaRange") && "70㎡及以上".equals(filters.get("areaRange"))) {
            filters.put("areaMin", 70);
            filters.remove("areaMax");
        }

        if (filters.containsKey("houseType") && filters.get("houseType") != null && !filters.get("houseType").equals("")) {
            String houseType = (String) filters.get("houseType");
            if ("3房及以上".equals(houseType)) {
                filters.put("houseType", "3房%,4房%,5房%");
            } else {
                filters.put("houseType", houseType + "%");
            }
        }
        total = houseMapper.getFilterCount(filters);
        filteredHouses = houseMapper.filterHouses(filters, offset, pageSize);

        // 为筛选后的房源加载图片
        for (House house : filteredHouses) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        // 构建返回结果
        Map<String, Object> response = new HashMap<>();
        response.put("total", total);
        response.put("houses", filteredHouses);
        response.put("pageNo", pageNo);
        response.put("pageSize", pageSize);

        return new Response<>(200, "筛选成功", response);
    }

    /**
     * 筛选房源---采用关键词搜索和筛选条件
     *
     * @param conditions 筛选条件
     * @param pageNo     当前页码
     * @param pageSize   每页记录数
     * @return
     */
    @Override
    public Response<Map<String, Object>> filterHousesByKey(Map<String, Object> conditions, int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;
        List<House> filteredHouses;
        int total;

        // 提取 filters 和 keyword
        Map<String, Object> filters = (Map<String, Object>) conditions.get("filters");
        String keyword = (String) conditions.get("keyword");

        // 过滤掉 filters 中值为 null 的键值对
        filters.entrySet().removeIf(entry -> entry.getValue() == null);

        // 特殊筛选条件处理
        if (filters.containsKey("areaRange") && "70㎡及以上".equals(filters.get("areaRange"))) {
            filters.put("areaMin", 70);
            filters.remove("areaMax");
        }

        if (filters.containsKey("houseType") && filters.get("houseType") != null && !filters.get("houseType").equals("")) {
            String houseType = (String) filters.get("houseType");
            if ("3房及以上".equals(houseType)) {
                filters.put("houseType", "3房%,4房%,5房%");
            } else {
                filters.put("houseType", houseType + "%");
            }
        }

        // 过滤条件中加入 houseStatus = 'available'
        filters.put("houseStatus", "available");

        // 判断是否有关键词
        if (keyword != null && !keyword.isEmpty()) {
            filteredHouses = houseMapper.searchAndFilterHouses(keyword, filters, offset, pageSize);
            total = houseMapper.getSearchAndFilterCount(keyword, filters);
        } else {
            total = houseMapper.getFilterCount(filters);
            filteredHouses = houseMapper.filterHouses(filters, offset, pageSize);
        }

        // 加载图片
        for (House house : filteredHouses) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        // 构建返回结果
        Map<String, Object> response = new HashMap<>();
        response.put("total", total);
        response.put("houses", filteredHouses);
        response.put("pageNo", pageNo);
        response.put("pageSize", pageSize);

        return new Response<>(200, "筛选成功", response);
    }

    /**
     * 房源分页查询 按照时间倒序
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Response<Map<String, Object>> getHousesByPage(int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;

        List<House> results = houseMapper.getHousesByPage(offset, pageSize,"available");
        int totalCount = houseMapper.getFilteredTotalHouses();

        // 过滤状态为available的房源
        results = results.stream()
                .filter(house -> "available".equals(house.getHouseStatus()))
                .collect(Collectors.toList());

        for (House house : results) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        Map<String, Object> responseData = new HashMap<>();
        responseData.put("total", totalCount);
        responseData.put("houses", results);
        responseData.put("pageNo", pageNo);
        responseData.put("pageSize", pageSize);

        return new Response<>(200, "查询成功", responseData);
    }


    /**
     * 根据房源ID获取房源信息----用户端，并增加浏览记录
     *
     * @param houseId
     * @param userId
     * @return
     */
    @Override
    public Response<House> getHouseById(int houseId, int userId) {
        try {
            // 查询房源信息
            House house = houseMapper.getHouseById(houseId);
            if (house == null) {
                return new Response<>(404, "房源不存在", null);
            }
            // 加载房源图片
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(houseId);
            house.setImageUrls(imageUrls);

            // 添加或更新浏览记录
            QueryWrapper<BrowsingHistory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("house_id", houseId);
            BrowsingHistory browsingHistory = browsingHistoryMapper.selectOne(queryWrapper);
            if (browsingHistory == null) {
                // 没有记录则创建，初始 viewCount 为 1
                BrowsingHistory newRecord = new BrowsingHistory();
                newRecord.setUserId(userId);
                newRecord.setHouseId(houseId);
                newRecord.setViewCount(1);
                browsingHistoryMapper.insert(newRecord);
            } else {
                // 已存在则 viewCount 加 1
                browsingHistory.setViewCount(browsingHistory.getViewCount() + 1);
                browsingHistoryMapper.updateById(browsingHistory);
            }

            return new Response<>(200, "查询成功", house);
        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }

    /**
     * 根据房源ID获取房源信息---房东端，不增加浏览记录
     *
     * @param houseId
     * @return
     */
    @Override
    public Response<House> getHouseByIdLandlord(int houseId) {
        try {
            // 查询房源信息
            House house = houseMapper.getHouseById(houseId);
            if (house == null) {
                return new Response<>(404, "房源不存在", null);
            }
            // 加载房源图片
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(houseId);
            house.setImageUrls(imageUrls);

            return new Response<>(200, "查询成功", house);
        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }


    /**
     * 根据房源的房东ID获取房东信息
     *
     * @param houseId 房源ID
     * @return
     */
    @Override
    public Response<Landlord> getLandlordByHouseId(int houseId) {
        try {
            Landlord landlord = houseMapper.getLandlordByHouseId(houseId);

            if (landlord == null) {
                return new Response<>(404, "房东信息不存在", null);
            }

            return new Response<>(200, "查询成功", landlord);
        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }

    /**
     * 收藏房源
     *
     * @param houseId 房源ID
     * @param userId  用户ID
     * @return
     */
    @Override
    @Transactional
    public Response<String> addFavorite(int houseId, int userId) {
        try {
            // 可选：先查询是否已经收藏，避免重复收藏
            QueryWrapper<Favorite> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("house_id", houseId);
            Favorite existing = favoriteMapper.selectOne(queryWrapper);
            if (existing != null) {
                return new Response<>(200, "房源已收藏", null);
            }

            // 创建收藏记录
            Favorite favorite = new Favorite();
            favorite.setUserId(userId);
            favorite.setHouseId(houseId);
            favoriteMapper.insert(favorite);

            return new Response<>(200, "收藏成功", null);
        } catch (Exception e) {
            return new Response<>(500, "收藏失败：" + e.getMessage(), null);
        }
    }

    /**
     * 取消收藏房源
     *
     * @param houseId 房源ID
     * @param userId  用户ID
     * @return
     */
    @Override
    @Transactional
    public Response<String> removeFavorite(int houseId, int userId) {
        try {
            // 根据房源ID和用户ID删除收藏记录
            QueryWrapper<Favorite> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("house_id", houseId);
            int deleted = favoriteMapper.delete(queryWrapper);
            if (deleted > 0) {
                return new Response<>(200, "取消收藏成功", null);
            } else {
                return new Response<>(404, "未找到收藏记录", null);
            }
        } catch (Exception e) {
            return new Response<>(500, "取消收藏失败：" + e.getMessage(), null);
        }
    }

    /**
     * 实现猜你喜欢的推荐逻辑：
     * 1. 查询用户在预约、浏览和消息表中对各房源的行为统计
     * 2. 根据各行为赋予不同的权重，计算每个房源的综合得分
     * 3. 对房源按照得分排序，进行分页后返回
     *
     * 协同过滤
     * 通过分析相似用户的行为数据，推荐其他用户喜欢的房源。例如，基于用户行为相似度或物品相似度。
     *
     * 基于内容的推荐
     * 根据房源的属性（如位置、户型、价格等）与用户历史行为匹配，推荐与用户喜好相似的房源。
     */
    @Override
    public Response<Map<String, Object>> getRecommendedHouses(int userId, int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;
        // Map: key 为房源ID，value 为推荐得分
        Map<Integer, Integer> houseScoreMap = new HashMap<>();

        // 定义权重
        int appointmentWeight = 10;
        int browsingWeight = 1;
        int messageWeight = 2;

        // ① 获取预约数据
        List<Map<String, Object>> appointmentCounts = appointmentMapper.getHouseAppointmentCountsByUser(userId);
        for (Map<String, Object> record : appointmentCounts) {
            Integer houseId = (Integer) record.get("houseId");
            int count = ((Number) record.get("count")).intValue();
            int score = count * appointmentWeight;
            houseScoreMap.put(houseId, houseScoreMap.getOrDefault(houseId, 0) + score);
        }

        // ② 获取浏览数据
        List<Map<String, Object>> browsingCounts = browsingHistoryMapper.getHouseBrowsingCountsByUser(userId);
        for (Map<String, Object> record : browsingCounts) {
            Integer houseId = (Integer) record.get("houseId");
            int count = ((Number) record.get("count")).intValue();
            int score = count * browsingWeight;
            houseScoreMap.put(houseId, houseScoreMap.getOrDefault(houseId, 0) + score);
        }

        // ③ 获取消息数据
        List<Map<String, Object>> messageCounts = messageMapper.getHouseMessageCountsByUser(userId);
        for (Map<String, Object> record : messageCounts) {
            Integer houseId = (Integer) record.get("houseId");
            int count = ((Number) record.get("count")).intValue();
            int score = count * messageWeight;
            houseScoreMap.put(houseId, houseScoreMap.getOrDefault(houseId, 0) + score);
        }

        // ④ 将房源ID按得分从高到低排序
        List<Map.Entry<Integer, Integer>> sortedEntries = new ArrayList<>(houseScoreMap.entrySet());
        sortedEntries.sort((e1, e2) -> e2.getValue() - e1.getValue());

        int total = sortedEntries.size();
        // 分页处理：抽取当前页的房源ID列表
        List<Integer> recommendedHouseIds = sortedEntries.stream()
                .skip(offset)
                .limit(pageSize)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        List<House> recommendedHouses;
        if (recommendedHouseIds.isEmpty()) {
            // 如果没有推荐数据，则降级为热门房源或直接分页查询所有房源
            recommendedHouses = houseMapper.getHousesByPage(offset, pageSize, "available");
        } else {
            // 批量查询推荐房源（只查询状态为available的房源）
            recommendedHouses = houseMapper.getHousesByIds(recommendedHouseIds);
            // 保持排序：根据 recommendedHouseIds 顺序重排
            Map<Integer, House> houseMap = recommendedHouses.stream()
                    .collect(Collectors.toMap(House::getId, h -> h));
            recommendedHouses = recommendedHouseIds.stream()
                    .map(houseMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }

        // ⑤ 如果推荐的房源不足最低数量（例如10个），则进行补充：
        int minCount = 10;
        if (recommendedHouses.size() < minCount) {
            int supplementCount = minCount - recommendedHouses.size();
            // 1、获取热度较高的房源（热门房源）
            List<House> hotHouses = houseMapper.getHousesByPage(0, 10, "available");
            // 2、如果已有推荐房源，则利用第一个房源的属性查询
            List<House> attributeHouses = new ArrayList<>();
            if (!recommendedHouses.isEmpty()) {
                House sample = recommendedHouses.get(0);
                attributeHouses = houseMapper.getHousesByAttributes(
                        sample.getHouseType(),
                        sample.getSubwayStation(),
                        sample.getArea(),
                        sample.getPrice(),
                        sample.getBusinessArea(),
                        "available",10
                );
            }
            // 3、合并热度房源和属性匹配房源，去除重复
            List<House> combinedFallback = new ArrayList<>();
            combinedFallback.addAll(hotHouses);
            combinedFallback.addAll(attributeHouses);
            Map<Integer, House> combinedMap = new LinkedHashMap<>();
            for (House h : combinedFallback) {
                combinedMap.put(h.getId(), h);
            }
            // 过滤掉已经在推荐列表中的房源
            Set<Integer> existingIds = recommendedHouses.stream()
                    .map(House::getId)
                    .collect(Collectors.toSet());
            List<House> supplement = combinedMap.values().stream()
                    .filter(h -> !existingIds.contains(h.getId()))
                    .limit(supplementCount)
                    .collect(Collectors.toList());
            recommendedHouses.addAll(supplement);
        }

        // 随机打散整个列表
        if (recommendedHouses.size() > 1) {
            Collections.shuffle(recommendedHouses);
        }

        // 更新 total，使其反映最终推荐列表的数量
        total = recommendedHouses.size();

        // 为每个房源加载图片
        for (House house : recommendedHouses) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        // 构造返回结果
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("total", total);
        responseData.put("houses", recommendedHouses);
        responseData.put("pageNo", pageNo);
        responseData.put("pageSize", pageSize);

        return new Response<>(200, "推荐成功", responseData);
    }


    /**
     * 获取用户所有收藏的房源
     *
     * @param userId   用户ID
     * @param pageNo   当前页码
     * @param pageSize 每页条数
     * @return
     */
    @Override
    public Response<Map<String, Object>> getFavoriteHouses(int userId, int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;
        try {
            List<House> favorites = houseMapper.getFavoriteHouses(userId, offset, pageSize);

            // 过滤状态为available的房源
            favorites = favorites.stream()
                    .filter(house -> "available".equals(house.getHouseStatus()))
                    .collect(Collectors.toList());

            int total = houseMapper.getFavoriteCount(userId);

            // 加载房源图片
            for (House house : favorites) {
                List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
                house.setImageUrls(imageUrls);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("total", total);
            result.put("houses", favorites);
            result.put("pageNo", pageNo);
            result.put("pageSize", pageSize);

            return new Response<>(200, "收藏房源查询成功", result);
        } catch (Exception e) {
            return new Response<>(500, "收藏房源查询失败：" + e.getMessage(), null);
        }
    }

    /**
     * 根据房东ID分页查询房源信息
     *
     * @param landlordId 房东ID
     * @param pageNo     当前页码
     * @param pageSize   每页记录数
     * @return 分页结果，包含房源列表、总数、页码、每页记录数等
     */
    @Override
    public Response<Map<String, Object>> getHousesByLandlordId(int landlordId, int pageNo, int pageSize,String status) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;

        // 1. 分页查询当前房东的房源列表
        List<House> houses = houseMapper.getHousesByLandlordId(landlordId, offset, pageSize, status);
        // 2. 统计该房东房源总数
        int total = houseMapper.getHouseCountByLandlordId(landlordId,status);

        // 3. 为每个房源加载图片
        for (House house : houses) {
            List<String> imageUrls = houseImageMapper.getImagesByHouseId(house.getId());
            house.setImageUrls(imageUrls);
        }

        // 4. 封装返回结果
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("total", total);
        responseData.put("houses", houses);
        responseData.put("pageNo", pageNo);
        responseData.put("pageSize", pageSize);

        return new Response<>(200, "查询成功", responseData);
    }

    /**
     * 更新房源信息
     *
     * @param updatedHouse 更新后的房源信息
     * @return Response对象，包含更新结果
     */
    @Override
    @Transactional
    public Response<String> updateHouse(House updatedHouse) {
        if (updatedHouse.getId() == null) {
            return new Response<>(400, "房源ID不能为空", null);
        }
        try {
            House existingHouse = houseMapper.getHouseById(updatedHouse.getId());
            if (existingHouse == null) {
                return new Response<>(404, "房源不存在", null);
            }
            updatedHouse.setHouseStatus("pending");
            updatedHouse.setRemarks("");
            int rows = houseMapper.updateHouse(updatedHouse);
            if (rows > 0) {
                // 先删除原有图片记录
                houseImageMapper.deleteByHouseId(updatedHouse.getId());
                // 插入新图片
                if (updatedHouse.getImageUrls() != null && !updatedHouse.getImageUrls().isEmpty()) {
                    for (String imageUrl : updatedHouse.getImageUrls()) {
                        HouseImage houseImage = new HouseImage();
                        houseImage.setHouseId(updatedHouse.getId());
                        houseImage.setImageUrl(imageUrl);
                        houseImageMapper.insert(houseImage);
                    }
                }
                return new Response<>(200, "修改成功", null);
            } else {
                return new Response<>(500, "修改失败", null);
            }
        } catch (Exception e) {
            return new Response<>(500, "修改失败：" + e.getMessage(), null);
        }
    }

    /**
     * 更新房源状态
     * @param houseId
     * @param newStatus
     * @return
     */
    @Override
    @Transactional
    public Response<String> updateHouseStatus(int houseId, String newStatus) {
        try {
            House existingHouse = houseMapper.getHouseById(houseId);
            if (existingHouse == null) {
                return new Response<>(404, "房源不存在", null);
            }

            // 更新状态
            int rows = houseMapper.updateHouseStatus(houseId, newStatus);
            if (rows > 0) {
                return new Response<>(200, "操作成功", null);
            } else {
                return new Response<>(500, "操作失败", null);
            }
        } catch (Exception e) {
            return new Response<>(500, "操作失败：" + e.getMessage(), null);
        }
    }

    /**
     * 获取待审核房源列表
     * @param pageNo 当前页码
     * @param pageSize 每页显示记录数
     * @return
     */
    @Override
    public Response<Map<String, Object>> getPendingHouses(int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;

        // 查询总数：状态为 pending
        QueryWrapper<House> countWrapper = new QueryWrapper<>();
        countWrapper.eq("house_status", "pending");
        int total = Math.toIntExact(houseMapper.selectCount(countWrapper));

        // 分页查询：状态为 pending（查询 house 表中所有字段，不涉及图片）
        QueryWrapper<House> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("house_status", "pending")
                .select("id", "landlord_id", "title", "description", "community", "address",
                        "house_type", "facilities", "price", "area", "floor", "longitude", "latitude",
                        "business_area", "subway_station", "house_status", "remarks", "lease", "traffic", "pay_type", "time","title_deed")
                .orderByDesc("time")
                .last("LIMIT " + offset + ", " + pageSize);
        List<House> houseList = houseMapper.selectList(queryWrapper);

        // 整合返回数据
        List<Map<String, Object>> houseSummaryList = new ArrayList<>();
        for (House house : houseList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", house.getId());
            map.put("landlordId", house.getLandlordId());
            map.put("title", house.getTitle());
            map.put("description", house.getDescription());
            map.put("community", house.getCommunity());
            map.put("address", house.getAddress());
            map.put("houseType", house.getHouseType());
            map.put("facilities", house.getFacilities());
            map.put("price", house.getPrice());
            map.put("area", house.getArea());
            map.put("floor", house.getFloor());
            map.put("longitude", house.getLongitude());
            map.put("latitude", house.getLatitude());
            map.put("businessArea", house.getBusinessArea());
            map.put("subwayStation", house.getSubwayStation());
            map.put("houseStatus", house.getHouseStatus());
            map.put("remarks", house.getRemarks());
            map.put("lease", house.getLease());
            map.put("traffic", house.getTraffic());
            map.put("payType", house.getPayType());
            map.put("time", house.getTime());
            map.put("titleDeed", house.getTitleDeed());

            // 获取该房源所有图片列表（从 house_images 表中查询）
            List<String> images = houseImageMapper.getImagesByHouseId(house.getId());
            map.put("houseImages", images);

            // 查询房东信息，返回房东姓名和联系方式
            Landlord landlord = landlordMapper.selectById(house.getLandlordId());
            if (landlord != null) {
                map.put("landlordName", landlord.getUsername());
                map.put("landlordPhone", landlord.getPhone());
            }
            houseSummaryList.add(map);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("houses", houseSummaryList);
        result.put("pageNo", pageNo);
        result.put("pageSize", pageSize);

        return new Response<>(200, "查询成功", result);
    }

    /**
     * 审核房源
     * @param houseId 房源ID
     * @param newStatus 目标状态："available"（上架）或 "removed"（下架）
     * @param remarks 备注信息，如果是审核通过可以为空，如果审核拒绝或下架，则需填写理由
     * @return
     */
    @Override
    @Transactional
    public Response<String> auditHouse(int houseId, String newStatus, String remarks) {
        // 1. 查询房源是否存在
        House house = houseMapper.getHouseById(houseId);
        if (house == null) {
            return new Response<>(404, "房源不存在", null);
        }

        // 2. 只有状态为 pending 的房源才允许审核
        if (!"pending".equals(house.getHouseStatus())) {
            return new Response<>(400, "该房源已被审核，不能重复操作", null);
        }

        // 3. 如果审核结果是 approved，且 remarks 为空，则默认设置为“审核通过”
        if ("approved".equals(newStatus) && (remarks == null || remarks.trim().isEmpty())) {
            remarks = "审核通过";
        }

        // 4. 获取当前管理员ID
        int adminId = StpUtil.getLoginIdAsInt();

        // 5. 执行条件更新：只有当当前状态为 pending 时才更新状态、备注和 admin_id
        int updateCount = houseMapper.auditHouseByAdmin(houseId, newStatus, remarks, adminId);
        if (updateCount == 0) {
            return new Response<>(409, "该房源正在被其他管理员审核，请审核其他房源", null);
        }

        // 6. 审核成功后，给房东发送邮件通知审核结果
        try {
            Landlord landlord = landlordMapper.selectById(house.getLandlordId());
            if (landlord != null && landlord.getEmail() != null) {
                String subject = "房源审核结果通知";
                String text;
                if ("approved".equals(newStatus)) {
                    text = "您好，您的房源【" + house.getTitle() + "】审核通过！快去把它上架吧！";
                } else {
                    text = "您好，很遗憾您的房源【" + house.getTitle() + "】审核未通过。\n拒绝理由：" + remarks;
                }
                sendEmailToLandlordWithHouse(landlord.getEmail(), subject, text);
            }
        } catch (Exception e) {
            System.out.println("邮件发送失败：" + e.getMessage());
        }

        return new Response<>(200, "审核成功", null);
    }


    /**
     * 房源审核结果通知----给房东发送邮件通知
     * @param landlordEmail 房东邮箱
     * @param subject 邮件主题
     * @param text 邮件内容
     */
    private void sendEmailToLandlordWithHouse(String landlordEmail, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail);
        message.setTo(landlordEmail);
        message.setSubject(subject);
        message.setText(text);

        try {
            mailSender.send(message);
        } catch (Exception e) {
            System.out.println("邮件发送失败：" + e.getMessage());
        }
    }

    /**
     * 获取房源详情
     * @param houseId 房源ID
     * @return
     */
    @Override
    @Transactional
    public Response<Boolean> tryLockHouse(int houseId) {
        int adminId = StpUtil.getLoginIdAsInt();
        House house = houseMapper.getHouseById(houseId);
        if (house == null) {
            return new Response<>(404, "房源不存在", false);
        }

        // 获取当前锁定信息
        Integer lockedBy = house.getLockedBy();
        Timestamp lockTime = house.getLockTime();

        // 如果房源已经被某个管理员锁定
        if (lockedBy != null) {
            // 如果是当前管理员锁定的，则更新锁定时间
            if (lockedBy.equals(adminId)) {
                int updateCount = houseMapper.lockHouse(houseId, adminId, new Timestamp(System.currentTimeMillis()), 5L);
                if (updateCount > 0) {
                    return new Response<>(200, "房源已重新锁定", true);
                } else {
                    return new Response<>(409, "房源重新锁定失败", false);
                }
            } else {
                // 如果是其他管理员锁定的，检查锁定是否超时（例如5分钟）
                if (lockTime != null) {
                    long minutesElapsed = Duration.between(lockTime.toInstant(), Instant.now()).toMinutes();
                    if (minutesElapsed >= 5) {
                        // 超过5分钟未操作，解除锁定，重新锁定房源
                        int updateCount = houseMapper.lockHouse(houseId, adminId, new Timestamp(System.currentTimeMillis()), 5L);
                        if (updateCount > 0) {
                            return new Response<>(200, "房源锁定成功", true);
                        } else {
                            return new Response<>(409, "房源锁定失败", false);
                        }
                    } else {
                        // 如果未超时，则表示房源已被其他管理员锁定
                        return new Response<>(409, "房源已被其他管理员锁定", false);
                    }
                } else {
                    return new Response<>(409, "锁定时间无效", false);
                }
            }
        } else {
            // 如果房源没有被锁定，进行锁定操作
            int updateCount = houseMapper.lockHouse(houseId, adminId, new Timestamp(System.currentTimeMillis()), 5L);
            if (updateCount > 0) {
                return new Response<>(200, "房源锁定成功", true);
            } else {
                return new Response<>(409, "房源锁定失败", false);
            }
        }
    }

    /**
     * 获取管理员审核的房源
     * @param adminId 当前管理员ID
     * @param pageNo 当前页码
     * @param pageSize 每页条数
     * @return
     */
    @Override
    public Response<Map<String, Object>> getAuditedHousesByAdmin(int adminId, int pageNo, int pageSize) {
        if (pageNo < 1) {
            pageNo = 1;
        }
        int offset = (pageNo - 1) * pageSize;

        // 查询总数：条件为 admin_id = 当前管理员ID
        LambdaQueryWrapper<House> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(House::getAdminId, adminId);
        int total = Math.toIntExact(houseMapper.selectCount(countWrapper));

        // 分页查询：条件为 admin_id = 当前管理员ID
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(House::getAdminId, adminId)
                .orderByDesc(House::getTime)
                // 不查询 image_urls，因为图片存放在 house_images 表中
                .select(House::getId, House::getLandlordId, House::getTitle, House::getDescription,
                        House::getCommunity, House::getAddress, House::getHouseType, House::getFacilities,
                        House::getPrice, House::getArea, House::getFloor, House::getLongitude, House::getLatitude,
                        House::getBusinessArea, House::getSubwayStation, House::getHouseStatus, House::getRemarks,
                        House::getLease, House::getTraffic, House::getPayType, House::getTime)
                .last("LIMIT " + offset + ", " + pageSize);
        List<House> houseList = houseMapper.selectList(queryWrapper);

        // 整合返回数据
        List<Map<String, Object>> houseSummaryList = new ArrayList<>();
        for (House house : houseList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", house.getId());
            map.put("title", house.getTitle());
            map.put("address", house.getAddress());
            map.put("houseType", house.getHouseType());
            map.put("price", house.getPrice());
            map.put("houseStatus", house.getHouseStatus());
            map.put("remarks", house.getRemarks());
            // 查询房源所有图片（通过外键在 house_images 表中获取）
            List<String> images = houseImageMapper.getImagesByHouseId(house.getId());
            map.put("houseImages", images);
            // 查询房东信息
            Landlord landlord = landlordMapper.selectById(house.getLandlordId());
            if (landlord != null) {
                map.put("landlordName", landlord.getUsername());
                map.put("landlordPhone", landlord.getPhone());
            }
            houseSummaryList.add(map);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("houses", houseSummaryList);
        result.put("pageNo", pageNo);
        result.put("pageSize", pageSize);

        return new Response<>(200, "查询成功", result);
    }


    /**
     * 管理员下架房源房源
     * @param houseId
     * @param remarks
     * @return
     */
    @Override
    @Transactional
    public Response<String> removeHouse(int houseId, String remarks) {
        // 查询房源
        House house = houseMapper.getHouseById(houseId);
        if (house == null) {
            return new Response<>(404, "房源不存在", null);
        }
        // 仅允许下架状态为 "available" 的房源
        if (!"available".equals(house.getHouseStatus())) {
            return new Response<>(400, "只有状态为已上架的房源才能下架", null);
        }
        // 检查下架理由不能为空
        if (remarks == null || remarks.trim().isEmpty()) {
            return new Response<>(400, "下架理由不能为空", null);
        }
        // 获取当前管理员ID
        int adminId = StpUtil.getLoginIdAsInt();
        // 执行条件更新：更新状态为 "removed"，同时更新 remarks 和 admin_id
        int updateCount = houseMapper.removeHouseByAdmin(houseId, "removed", remarks, adminId, "available");
        if (updateCount == 0) {
            return new Response<>(409, "该房源状态已发生变化，请刷新数据", null);
        }
        // 发送邮件通知房东
        try {
            Landlord landlord = landlordMapper.selectById(house.getLandlordId());
            if (landlord != null && landlord.getEmail() != null) {
                String subject = "房源下架通知";
                String text = "您好，您的房源【" + house.getTitle() + "】已下架。\n原因：" + remarks;
                sendEmailToLandlord(landlord.getEmail(), subject, text);
            }
        } catch (Exception e) {
            System.out.println("邮件发送失败：" + e.getMessage());
        }
        return new Response<>(200, "下架成功", null);
    }


    private void sendEmailToLandlord(String landlordEmail, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail);
        message.setTo(landlordEmail);
        message.setSubject(subject);
        message.setText(text);
        try {
            mailSender.send(message);
        } catch (Exception e) {
            System.out.println("邮件发送失败：" + e.getMessage());
        }
    }

}

